define(['utils', 'base'], function (Utils, baseClass) {
    "use strict";

    var Component = function (config) {
        var _this = this;

        Component.baseConstructor.call(this, config);

        this.displayMember = this.config.displayMember;
        this.delayLoadData = config.delayLoadData === true;

        if (!this.displayMember) {
            console.error("请设置有效的displayMember");
        }

        if (!this.valueData) {
            this.valueData = {};
            this.valueData.id = "";
            this.valueData[this.displayMember] = "";
        }

        this.datasource = config.datasource || [];
        this.value = this.value || config.value;

        this.$el.addClass("yy-autocomplete");
        this.input = $("<input type='text' placeholder='"+this.config.placeholder+"'/>");
        this.$el.append(this.input);

        var changeMethodName = config.comKey + "_change";
        this.changeMethod = this.pageview.plugin[changeMethodName];

        this.$el.bind("input propertychange", function (e) {
            e.stopPropagation();
            e.preventDefault();
            _this.pageview.pageManager.triggerBodyClickWithoutSelf(_this);

            _this.selectedItem = "";
            _this.valueData.id = "";
            _this.valueData[_this.displayMember] = "";

            if (!_this.autocompleteTimeout) {
                _this.autocompleteTimeout = setTimeout(function () {
                    _this.freshLayout();
                }, 500);
            } else {
                clearTimeout(_this.autocompleteTimeout);

                _this.autocompleteTimeout = setTimeout(function () {
                    _this.freshLayout();
                }, 500);
            }

        });

        this.$el.bind("click", function (e) {
            e.stopPropagation();
            e.preventDefault();
            _this.pageview.pageManager.triggerBodyClickWithoutSelf(_this);

            _this.show();
        });

        this.input.bind("keydown", function (e) {
            if (e.keyCode === 40) {
                //下
                e.stopPropagation();
                e.preventDefault();
                _this._selectDown();
            } else if (e.keyCode === 38) {
                e.stopPropagation();
                e.preventDefault();
                _this._selectUp();
                //上
            } else if (e.keyCode === 13 || e.keyCode === 9) {
                e.stopPropagation();
                e.preventDefault();
                _this.hide();
                _this.input.blur();
            }
        });

        this.hasBinData = false;

        this.init();
    };
    Utils.extendClass(Component, baseClass);

    Component.prototype.init = function () {
        var _this = this;
        this.autocomplete = $("<div class='yy-autocomplete-wrap'></div>");
        if (this.config.autocompleteStyle) {
            this.autocomplete.css(this.config.autocompleteStyle);
        }

        this.autocompleteinner = $("<div class='yy-autocomplete-wrap-inner'></div>");
        this.autocomplete.append(this.autocompleteinner);

        this.autocomplete.bind("click", function (e) {
            _this.itemClick(e);
        });

        this.pageview.$el.append(this.autocomplete);

        // 初始化时请求参数
        if (!this.hasBinData) {
            this.freshLayout();
        }

    };

    Component.prototype.show = function () {
        // 保险校验
        if (!this.hasBinData) {
            this.freshLayout();
        } else {
            this.showAutoComplete();
        }
    };

    Component.prototype.freshLayout = function () {
        var _this = this;

        this.changeMethod.call(this.pageview.plugin, this, {
            success: function (data) {
                _this.hasBinData = true;
                _this.datasource = data;

                _this._createItems();

                if (_this.delayLoadData) {
                    _this.showAutoComplete();
                }
            },
            error: function (e) {
                console.error(e);
            },
            value: _this.input.val()
        });
    };

    Component.prototype.showAutoComplete = function () {
        var _this = this;

        var pos = this.$el.offset();
        var h = this.$el.height();

        this.autocomplete.css({top: (pos.top + h + 2) + "px", left: pos.left + "px", "visibility": "visible"});
        this.pageview.pageManager.regeistBodyClick(this.id, function () {
            _this.hide();
        });
    };

    Component.prototype._createItems = function () {
        var _this = this;
        this.items = {};
        var item = "",
            $item;
        if (this.datasource.length > 0) {
            this.autocompleteinner.empty();
            for (var i = 0, j = this.datasource.length; i < j; i++) {
                var itemMark = "item_" + i;
                var itemdata = this.datasource[i];
                var val = itemdata[this.displayMember];
                item += "<div data-item='" + itemMark + "' class='yy-autocomplete-item'>" + val + "</div>";
                $item = $("<div data-item='" + itemMark + "' class='yy-autocomplete-item'>" + val + "</div>");
                this.items[itemMark] = {dom: $item, data: itemdata};
                this.autocompleteinner.append($item);
            }
        } else {
            this.autocompleteinner.html($("<div class='yy-autocomplete-no-data'>未查询到相关数据</div>"));
        }
    };

    Component.prototype.setValue = function (val) {

        if (this.config.primaryKey) {
            this.setValueByItemData(val);
            return;
        }

        if (this.datasource.length === 0) {
            this.value = val;
            this.valueData = val;
            this.input.val(val);
            return;
        }

        var selectedInfo;

        for (var key in this.items) {
            var item = this.items[key];
            var data = item.data;
            if (data[this.displayMember] == val) {
                selectedInfo = item;

                break;
            }
        }

        if (this.selectedItem) {
            this.selectedItem.removeClass("yy-autocomplete-item-selected");
        }

        this.selectedItem = selectedInfo.dom;
        this.valueData = selectedInfo.data;
        this.selectedItem.addClass("yy-autocomplete-item-selected");
        this.input.val(selectedInfo.data[this.displayMember]);
    };

    Component.prototype.itemClick = function (e) {
        e.stopPropagation();
        e.preventDefault();
        this.setItemSelected(e.target);
        this.hide();
    };

    Component.prototype.setItemSelected = function (item) {
        var itemMark = item.getAttribute("data-item");
        if (itemMark) {
            var itemInfo = this.items[itemMark];
            if (this.selectedItem) {
                this.selectedItem.removeClass("yy-autocomplete-item-selected");
            }
            this.selectedItem = itemInfo.dom;

            this.valueData = itemInfo.data;
            this.selectedItem.addClass("yy-autocomplete-item-selected");

            var val = itemInfo.data[this.displayMember];
            this.input.val(val);

            if (this.changeMethod) {
                this.changeMethod.call(this.pageview.plugin, this, {
                    value: val,
                    success: function () {

                    }, error: function () {

                    }
                });
            }
        }
    };

    Component.prototype.hide = function () {
        this.autocomplete.css({visibility: "hidden"});
        this.pageview.pageManager.cancelBodyClick(this.id);
    };

    Component.prototype.setValueByItemData = function (val) {
        val = val || this.config.defaultData;
        var primaryKey = this.config.primaryKey;

        if (!Utils.isJSON(val)) {
            console.error("autocomplete value必须为JSON数组");
        }
        if (this.datasource.length === 0) {
            this.value = val;

            this.valueData = val;
            this.input.val(val[this.displayMember]);
            return;
        }

        var selectedInfo;

        for (var key in this.items) {
            var item = this.items[key];
            var data = item.data;
            if (data[primaryKey] == val[primaryKey]) {
                selectedInfo = item;
                break;
            }
        }

        if (this.selectedItem) {
            this.selectedItem.removeClass("yy-autocomplete-item-selected");
        }

        this.selectedItem = selectedInfo.dom;
        this.valueData = selectedInfo.data;
        this.selectedItem.addClass("yy-autocomplete-item-selected");
        this.input.val(selectedInfo.data[this.displayMember]);
    };

    Component.prototype._selectDown = function (e) {
        if (this.selectedItem && this.datasource.length > 0) {
            var next = this.selectedItem.next();
            if (next && next[0]) {
                this.setItemSelected(next[0]);
            }
        }
        this.setPos();
    };

    Component.prototype._selectUp = function (e) {
        if (this.selectedItem && this.datasource.length > 0) {
            var prev = this.selectedItem.prev();
            if (prev && prev[0]) {
                this.setItemSelected(prev[0]);
            }
        }
        this.setPos();
    };

    Component.prototype.setPos = function () {
        if (this.datasource.length > 0) {
            if (!this.selectedItem) {
                this.selectedItem = this.items['item_0'].dom;
                this.items['item_0'].dom.addClass('yy-autocomplete-item-selected');
                this.setItemSelected(this.selectedItem[0]);
            }
            var itempos = this.selectedItem.position();
            var st = this.autocompleteinner.scrollTop();
            var pos = itempos.top + st;
            pos -= 56;
            this.autocompleteinner.scrollTop(pos);
        }
    };

    return Component;
});
